#!/bin/bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# 检查是否以root用户运行
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误：请使用sudo或root用户运行此脚本${NC}"
exit 1
fi

# 1. 部署Fabric网络环境
function deploy_fabric() {
echo -e "${YELLOW}[1/3] 开始部署Fabric网络环境...${NC}"

# 克隆仓库
echo -e "${GREEN}>>> 克隆fabric-deploy仓库${NC}"
git clone https://gitee.com/songer123/fabric-deploy.git || {
echo -e "${RED}错误：git克隆失败${NC}"
exit 1
}

# 更新工具
echo -e "${GREEN}>>> 更新系统工具${NC}"
apt update || {
echo -e "${RED}错误：apt更新失败${NC}"
exit 1
}

# 安装依赖
echo -e "${GREEN}>>> 安装必要依赖${NC}"
apt install -y curl jq docker-compose || {
echo -e "${RED}错误：依赖安装失败${NC}"
exit 1
}

# 运行部署脚本
echo -e "${GREEN}>>> 执行部署脚本${NC}"
cd fabric-deploy/ && sudo bash deploy.sh || {
echo -e "${RED}错误：部署脚本执行失败${NC}"
exit 1
}

echo -e "${GREEN}[✓] Fabric网络部署完成${NC}"
}

# 2. 准备链码
function prepare_chaincode() {
echo -e "${YELLOW}[2/3] 准备链码文件...${NC}"

# 创建并进入工作目录
mkdir -p work && cp -r ./test/* ./work/ || {
echo -e "${RED}错误：链码目录准备失败${NC}"
exit 1
}

cd work && rm -rf test.go || {
echo -e "${RED}错误：链码目录准备失败${NC}"
exit 1
}

# 编辑链码文件
echo -e "${GREEN}>>> 创建work.go链码文件${NC}"
cat > work/work.go << 'EOF'
package main

import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)

type SmartContract struct {
contractapi.Contract
}

type Asset struct {
ID    string `json:"id"`
Owner string `json:"owner"`
Name  string `json:"name"`
Info  string `json:"info"`
}

/* 资产上链 */
func (s *SmartContract) Create(ctx contractapi.TransactionContextInterface,
id string, owner string, name string, info string) (string, error) {

asset := Asset{ID: id, Owner: owner, Name: name, Info: info}
kvBytes, _ := json.Marshal(asset)
err := ctx.GetStub().PutState(id, kvBytes)
if err != nil {
return "", fmt.Errorf("Failed to set asset: %s", err.Error())
}
return id, nil
}

/* 查询资产 */
func (s *SmartContract) Query(ctx contractapi.TransactionContextInterface,
id string) (*Asset, error) {

kvBytes, err := ctx.GetStub().GetState(id)
if err != nil {
return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())
}
if kvBytes == nil {
return nil, fmt.Errorf("%s does not exist", id)
}
kv := new(Asset)
_ = json.Unmarshal(kvBytes, kv)
return kv, nil
}

/* 转移资产 */
func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface,
id string, owner string) error {

kvBytes, err := ctx.GetStub().GetState(id)
if err != nil {
return fmt.Errorf("Failed to read from world state. %s", err.Error())
}
if kvBytes == nil {
return fmt.Errorf("%s does not exist", id)
}
asset := new(Asset)
_ = json.Unmarshal(kvBytes, asset)
asset.Owner = owner
assetBytes, _ := json.Marshal(asset)
err = ctx.GetStub().PutState(id, assetBytes)
if err != nil {
return fmt.Errorf("Failed to set asset: %s", err.Error())
}
return nil
}

func main() {
chaincode, err := contractapi.NewChaincode(new(SmartContract))
if err != nil {
fmt.Printf("Error create fabcar chaincode: %s", err.Error())
return
}
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting fabcar chaincode: %s", err.Error())
}
}
EOF

echo -e "${GREEN}[✓] 链码文件准备完成${NC}"
}

# 3. 安装链码
function install_chaincode() {
echo -e "${YELLOW}[3/3] 安装链码...${NC}"

# 返回上级目录并安装链码
cd .. && sudo bash code.sh work || {
echo -e "${RED}错误：链码安装失败${NC}"
exit 1
}

echo -e "${GREEN}[✓] 链码安装完成${NC}"
}

# 主执行流程
function main() {
deploy_fabric
prepare_chaincode
install_chaincode

echo -e "\n${GREEN}============================================="
echo " Fabric网络和链码部署全部完成!"
echo " 请检查截图确认是否成功"
echo -e "=============================================${NC}"
}

main